/**
 * 
 */
package neptune.manager.validator.core;

import neptune.manager.NeptuneManager;
import neptune.manager.model.topology.IPAddress;
import neptune.manager.model.topology.Link;
import neptune.manager.model.topology.Node;
import neptune.manager.model.topology.Topology;
import neptune.manager.utils.Logger.MessageType;
import neptune.manager.validator.Validator;
import neptune.manager.validator.ValidatorResult;
import neptune.manager.validator.rules.topology.ExperimentIPAddressRangeRule;
import neptune.manager.validator.rules.topology.IPAddressUniquenessRule;
import neptune.manager.validator.rules.topology.LinkEndPointCoerenceRule;
import neptune.manager.validator.rules.topology.LinkSingleEndPointForIfaceRule;
import neptune.manager.validator.rules.topology.MACAddressesUniquenessRule;
import neptune.manager.validator.rules.topology.OLPIEndPointIPCoerence;
import neptune.manager.validator.rules.topology.TopologyLinksUniquenessRule;
import neptune.manager.validator.rules.topology.TopologyNameRule;
import neptune.manager.validator.rules.topology.TopologyNodesUniquenessRule;

/**
 * @author Roberto Bifulco [RobertoBifulco.it] [info@robertoBifulco.it]
 * 
 */
public class CoreTopologyValidator extends Validator<Topology> {

	protected Validator<Node> nodeValidator;
	protected Validator<Link> linkValidator = new CoreLinkValidator();

	public CoreTopologyValidator(NeptuneManager neptuneManager,
			IPAddress experimentSubnet) {
		addRule(new TopologyNameRule());
		addRule(new TopologyNodesUniquenessRule());
		addRule(new MACAddressesUniquenessRule(neptuneManager));
		addRule(new IPAddressUniquenessRule(neptuneManager));
		addRule(new TopologyLinksUniquenessRule());
		addRule(new LinkEndPointCoerenceRule());
		addRule(new LinkSingleEndPointForIfaceRule());
		addRule(new ExperimentIPAddressRangeRule(experimentSubnet));
		addRule(new OLPIEndPointIPCoerence());

		nodeValidator = new CoreNodeValidator(neptuneManager
				.getControlIPAddresRange());
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see neptune.manager.validator.TopologyValidator#getName()
	 */
	@Override
	public String getName() {
		return "CoreTopologyValidator";
	}

	/*
	 * (non-Javadoc)
	 * 
	 * @see
	 * neptune.manager.validator.TopologyValidator#validationAlgorithm(neptune
	 * .manager.model.topology.Topology,
	 * neptune.manager.validator.ValidatorResult)
	 */
	@Override
	protected ValidatorResult validationAlgorithm(Topology toValidate,
			ValidatorResult result) {

		result.getLog().addMessage(
				"Validating topology '" + toValidate.getName() + "'",
				MessageType.NORMAL);

		for (Node node : toValidate.getNodes()) {
			nodeValidator.validate(node, result);
		}

		for (Link link : toValidate.getLinks()) {
			linkValidator.validate(link, result);
		}

		return result;
	}

}
